const minio = require('../minio');
const router = require('../../router');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const axios = require('axios');

const {
  pagination
} = require('../../../utils');

const {
  verifyToken
} = require('../../../lib');

// service mesh 同步备份
const SERVICE_MESH_URL_MAP = {
  'veeui':  'xxx'
}

router.post('/listObjects', function (req, res) {
  const params = req.body;

  const {
    bucketName,
    prefix,
    pageSize,
    pageNum,
    key
  } = params;

  const stream = minio(key).listObjects(bucketName, prefix || '', false)

  let flag = false,
    data = [];

  stream.on('data', function (obj) {
    data.push(obj);
    flag = true;
  })

  stream.on('error', function (err) {
    console.log(err)

    data = err;
    flag = false;
  })

  stream.on('end', function (err) {
    if (flag) {
      // 分页处理
      res.json({
        code: "0",
        data: pageNum == -1 ? {
          total: data.length,
          lists: data
        } : {
          total: data.length,
          lists: pagination(data, pageSize || 10, pageNum || 1)
        },
        msg: '成功',
        success: true
      })
    } else {
      res.json({
        code: "-1",
        data: err,
        msg: '失败',
        success: false
      })
    }
  })
})

router.post('/getObject', function (req, res) {
  const params = req.body;

  const {
    bucketName,
    objectName,
    key
  } = params;

  minio(key).getObject(bucketName, objectName, function (err, dataStream) {
    if (err) {
      return console.log(err)
    }
    let size = 0;

    dataStream.on('data', function (chunk) {
      size += chunk.length
    })
    dataStream.on('end', function () {
      res.json({
        code: "0",
        data: size,
        msg: '成功',
        success: true
      })
    })
    dataStream.on('error', function (err) {
      res.json({
        code: "-1",
        data: err,
        msg: '失败',
        success: false
      })
    })
  })
})

router.post('/statObject', function (req, res) {
  const params = req.body;

  const {
    bucketName,
    objectName,
    key
  } = params;

  minio(key).statObject(bucketName, objectName, function (err, stat) {
    if (err) {
      return console.log(err)
    }

    res.json({
      code: "0",
      data: stat,
      msg: '成功',
      success: true
    })
  })
})

router.post('/presignedGetObject', function (req, res) {
  const params = req.body;

  const {
    bucketName,
    objectName,
    expiry,
    key
  } = params;

  minio(key).presignedGetObject(bucketName, objectName, expiry || 7 * 24 * 60 * 60, function (err, presignedUrl) {
    if (err) {
      return console.log(err)
    }

    res.json({
      code: "0",
      data: presignedUrl,
      msg: '成功',
      success: true
    })
  })
})

const promisifyPutFolder = ({env, key, bucketName, folder},cb) => {
  return new Promise((resolve, reject) => {
    cb(key).putObject(bucketName, folder + '/', '', '', '', function (err, etag) {
      if (err) {
        return reject({
          code: "-1",
          data: {
            env,
            error: err
          },
          msg: '失败',
          success: false
        })
      } else {
        return resolve({
          code: "0",
          data: {
            env,
            etag: etag
          },
          msg: '成功',
          success: true
        })
      }
    })
  })
}

router.post('/putFolder', async function (req, res) {
  console.log('/putFolder', req.body);
  const verifyResponse = await verifyToken(req.body.authorization, 'imagepic');

  console.log('verifyResponse', verifyResponse)

  const bucketName = req.body.bucket,
    folder = req.body.folder,
    key = req.body.key;

  if (!verifyResponse.flag) {
    return res.json({
      code: "-1",
      data: verifyResponse.msg,
      msg: '未满足权限',
      success: false
    })
  } else {
      const p1 = promisifyPutFolder({env:'测试区', key, bucketName, folder}, minio);

      const p2 = new Promise(async (resolve, reject) => {
        const res = await axios.post(SERVICE_MESH_URL_MAP[`${key}`] + 'imagepic/object/putFolder', {
          key, 
          bucketName, 
          folder
        });
  
        if(res.data.success) {
          return resolve({
            code: res.data.code,
            data: {
              env: '生产区',
              etag: res.data.data
            },
            msg: res.data.msg,
            success: res.data.success
          })
        } else {
          return reject({
            code: res.data.code,
            data: {
              env: '生产区',
              error: res.data.data
            },
            msg: res.data.msg,
            success: res.data.success
          })
        }
      })

      Promise
        .all([p1, p2])
        .then(results => {
          console.log('/imagepic/object/putFolder results', results);
          return res.json({
            code: "0",
            data: {
              etag: results[0].data.etag,
              _etag: results[1].data.etag
            },
            msg: '成功',
            success: true
          })
        })
        .catch(error => {
          console.log('/imagepic/object/putFolder error', error)
          return res.json({
            code: "-1",
            data: {
              env: error.data.env,
              error: error.data.error
            },
            msg: '失败',
            success: false
          })
        })
  }


});

// putObject核心逻辑 promise化
const promisifyPutObject = ( { env, key, bucketName, fullName, fileName, file, stats, ext }, cb ) => {
  return new Promise((resolve, reject) => {
    cb(key).putObject(bucketName, fullName, fs.createReadStream(file), stats.size, {
      'Content-Type': `image/${ext}`
    }, function (err, etag) {
      if (err) {
        reject({
          code: "-1",
          data: {
            env,
            error: err
          },
          msg: '失败',
          success: false
        })
      } else {
        resolve({
          code: "0",
          data: {
            env,
            etag: etag
          },
          msg: '成功',
          success: true
        })
      }
    })
  })
}

router.post('/putObject', multer({
  dest: path.resolve(__dirname, '../../../../db/__temp__')
}).single('file'), async function (req, res) {
  console.log('/putObject', req.file, req.headers);
  const verifyResponse = await verifyToken(req.headers.authorization, 'imagepic');

  console.log('verifyResponse', verifyResponse)
  const useExt = ext => {
    switch (ext) {
      case 'svg':
        return 'svg+xml'
      default:
        return ext
    }
  }

  const bucketName = req.headers.bucket,
    folder = req.headers.folder,
    key = req.headers.key,
    originName = req.file['originalname'],
    file = req.file['path'],
    ext = useExt(path.extname(req.file['originalname']).slice(1)),
    fileName = req.file['filename'];
  console.log('folder', folder);
  console.log('ext', ext.slice(1));

  if (!verifyResponse.flag) {
    fs.unlink(path.resolve(__dirname, `../../../../db/__temp__/${fileName}`), function (err) {
      if (err) {
        console.error(`删除文件 ${fileName} 失败，失败原因：${err}`)
      }
      console.log(`删除文件 ${fileName} 成功`)
    });
    return res.json({
      code: "-1",
      data: verifyResponse.msg,
      msg: '未满足权限',
      success: false
    })
  } else {
    const fullName = folder ? `${folder}/${originName}` : `${originName}`;
    fs.stat(file, function (err, stats) {
      if (err) {
        return console.log(err)
      }
      

      const p1 = promisifyPutObject({ env:'测试区', key, bucketName, fullName, fileName, file, stats, ext }, minio);

      // const p2 = promisifyPutObject({ env:'生产区', key, bucketName, fullName,fileName, file, stats, ext }, _minio);
      

      const p2 = new Promise((resolve, reject) => {
        axios({
          url: SERVICE_MESH_URL_MAP[`${key}`] + 'imagepic/object/transferObject',
          method: 'post',
          data: {
            // buffer: fs.readFileSync(path.resolve(__dirname, `../../../../db/__temp__/${fileName}`))
            key
          },
          params: {
            fileName
          }
        }).then(r => {
          console.log('r', r.data)
          if(res.success) {
            return true;
          } else {
            return false;
          }
        }).then(() => {
          axios.post(SERVICE_MESH_URL_MAP[`${key}`] + 'imagepic/object/putObject', {
            key, 
            bucketName, 
            fullName, 
            fileName, 
            stats, 
            ext
          }).then(res => {
            if(res.data.success) {
              return resolve({
                code: res.data.code,
                data: {
                  env: '生产区',
                  etag: res.data.data.etag
                },
                msg: res.data.msg,
                success: res.data.success
              })
            } else {
              return reject({
                code: res.data.code,
                data: {
                  env: '生产区',
                  error: res.data.data
                },
                msg: res.data.msg,
                success: res.data.success
              })
            }
          }).catch(err => {
            if(err) throw err;
          })
        }).catch(err => {
          if(err) throw err;
        });
        

      })

      Promise
        .all([p1, p2])
        .then(results => {
          console.log('/imagepic/object/putObject results', results);
          fs.unlink(path.resolve(__dirname, `../../../../db/__temp__/${fileName}`), function (err) {
            if (err) {
              console.error(`删除文件 ${fileName} 失败，失败原因：${err}`)
            }
            console.log(`删除文件 ${fileName} 成功`)
          });
          return res.json({
            code: "0",
            data: {
              etag: results[0].data.etag,
              _etag: results[1].data.etag
            },
            msg: '成功',
            success: true
          })
        })
        .catch(error => {
          console.log('/imagepic/object/putObject error', error)
          return res.json({
            code: "-1",
            data: {
              env: error.data.env,
              error: error.data.error
            },
            msg: '失败',
            success: false
          })
        })
    })
  }


});

const promisifyRemoveObject = ({env, key, bucketName, objectName}, cb) => {
  return new Promise((resolve, reject) => {
    cb(key).removeObject(bucketName, objectName, function (err) {
      if (err) {
        return reject({
          code: "-1",
          data: {
            env,
            error: err
          },
          msg: '失败',
          success: false
        })
      } else {
        return resolve({
          code: "0",
          data: {
            env
          },
          msg: '成功',
          success: true
        })
      }
    })
  })
}

router.post('/removeObject', async function (req, res) {
  console.log('/removeObject', req.body, req.headers);
  const verifyResponse = await verifyToken(req.headers.authorization, 'imagepic');

  if (!verifyResponse.flag) {
    return res.json({
      code: "-1",
      data: verifyResponse.msg,
      msg: '未满足权限',
      success: false
    })
  } else {
    const {
      bucketName,
      objectName,
      key
    } = req.body;

    const p1 = promisifyRemoveObject({env: '测试区', key, bucketName, objectName }, minio)
    
    // const p2 = promisifyRemoveObject({env: '生产区', key, bucketName, objectName }, _minio)
    const p2 = new Promise(async (resolve, reject) => {
      const res = await axios.post(SERVICE_MESH_URL_MAP[`${key}`] + 'imagepic/object/removeObject', {
        key, bucketName, objectName
      });

      if(res.data.success) {
        return resolve({
          code: res.data.code,
          data: {
            env: '生产区'
          },
          msg: res.data.msg,
          success: res.data.success
        })
      } else {
        return reject({
          code: res.data.code,
          data: {
            env: '生产区',
            error: res.data.data
          },
          msg: res.data.msg,
          success: res.data.success
        })
      }
    })

    Promise
      .all([p1, p2])
      .then(results => {
        console.log('/imagepic/object/removeObject results', results)
        return res.json({
          code: "0",
          data: {},
          msg: '成功',
          success: true
        })
      })
      .catch(error => {
        console.log('/imagepic/object/removeObject error', error)
        res.json({
          code: "-1",
          data: {
            env: error.data.env,
            error: error.data.error
          },
          msg: '失败',
          success: false
        })
      })
  }
});

module.exports = router;